const ObjectId = require('mongodb').ObjectId
// 过滤掉接口不需要返回的字段
const FILTER_PARAMS = {
  _id: 0,
  __v: 0
}

module.exports = app => {
  class FileService extends app.Service {
    /**
     * 获取文件列表
     * @param {String} dirId 文件夹id
     */
    async list(data) {
      try {
        return new Promise((resolve, reject) => {
          data.userId = this.ctx.state.user.id
          this.ctx.model.File.find({
            ...data
          }, FILTER_PARAMS).lean().exec((err, res) => {
            if (err) {
              reject(err)
            } else {
              resolve(res)
            }
          })
        })
      } catch (error) {
        console.log(error)
      }
    }

    /**
     * 添加文件/文件夹
     * 当传入单个文件  对象格式
     * 当传入多个文件  数组格式
     */
    async upload(data) {
      try {
        return new Promise((resolve, reject) => {
          if(data.fileMultiple && Array.isArray(data.fileMultiple)){
            // 多个文件
            let result = this.uploadMany(data.fileMultiple)
            resolve(result)
          }else{
            // 单个文件
            let result = this.uploadOne(data)
            resolve(result)
          }
        })
      } catch (error) {
        console.log(error)
      }
    }


    /**
     * 添加文件/文件夹
     * @param {String} parentId 所属文件夹id
     * @param {String} fileName 文件名
     * @param {String} fileSize 文件大小
     * @param {String} fileType 文件类型  .  all image docs video music other
     * @param {String} fileExtension 文件后缀名  . jpg png mp4 ...
     * @param {String} fileUrl  文件地址
     * @return {Object} 添加的结果
     */
    async uploadOne(data) {
      try {
        return new Promise((resolve, reject) => {
          // TODO 需要添加 验证数据完整性 正确性
          data.fileId = new ObjectId() // 防止id重复
          data.userId = this.ctx.state.user.id
          this.ctx.model.File({
            ...data
          }).save((err, res) => {
            if (err) {
              reject(err)
              return
            }
            resolve(res)
          })
        })
      } catch (error) {
        console.log(error)
      }
    }

    async uploadMany(data) {
      try {
        return new Promise((resolve, reject) => {
          // TODO 需要添加 验证数据完整性 正确性
          data.map(ele => {
            ele.fileId = new ObjectId()
            ele.userId = this.ctx.state.user.id
            return ele
          })
          this.ctx.model.File.insertMany(data,(err, res) => {
            if (err) {
              reject(err)
              return
            }
            resolve(res)
          })
        })
      } catch (error) {
        console.log(error)
      }
    }

    /**
     * 修改文件名
     * @param {String} old_name 旧文件名
     * @param {String} new_name 新文件名
     * @param {String} fileId 文件id
     * @return {Boolean} 是否修改成功
     */
    async update (oldData = {}, newData){
      return new Promise((resolve, reject) => {
          this.ctx.model.File.updateOne(oldData, newData).lean().exec((err, docs) => {
              if (err) {
                  console.log(err)
                  reject(err)
              } else {
                  resolve(docs)
              }
          })
      })
  }
    /**
     * 删除文件
     * @param {String} fileId 文件id
     * @return {Object} 删除的结果
     */
    async remove(fileId) {
      try {
        return new Promise(async (resolve, reject) => {
          let userId = this.ctx.state.user.id
          this.ctx.model.File.deleteOne({
              fileId, userId
            })
            .lean().exec(async (err, res) => {
              if (err) {
                reject(err)
                return
              }
              resolve(res)
            })

        })
      } catch (error) {
        console.log(error)
      }

    }
    async moveFile() {

    }

    /**
     * 搜索文件
     * @param {String} fileName 文件名称
     */
    async search(data) {
      try {
        console.log(data)
        const {fileName} = data
        let userId = this.ctx.state.user.id
        return new Promise((resolve, reject) => {
          this.ctx.model.File.find({
            fileName: {
              $regex: fileName,
              $options: 'i'
            },
            userId
          }, FILTER_PARAMS).sort({
            createTime: -1
          }).lean().exec((err, res) => {
            if (err) {
              reject(err)
            } else {
              resolve(res)
            }
          })
        })
      } catch (error) {
        console.log(error)
      }
    }
  }
  return FileService
}
